using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;

public class SkillEditor :Editor
{
    [MenuItem("GameObject/CreateStateConfig")]

    public static void CreateStateConfig()
    {
        var go  = Selection.activeGameObject;
        if(go == null)
        {
            return;
        }

        var director = go.GetComponent<PlayableDirector>();
        if (director == null)
        {
            return;
        }

        EffectConfig _track_effect_config = new EffectConfig();

        double anm_length = 0;
        Dictionary<int,TrackAsset> tracekSet = new Dictionary<int,TrackAsset>();   //0 动作 1特效 2特效资源
        foreach (PlayableBinding item in director.playableAsset.outputs)
        {
            var track = item.sourceObject as TrackAsset;
            if (track is AnimationTrack _animationTrack) //动作轨道 用来获取他的整个动作时长 用来计算 其他的时间
            {
                Debug.Log(_animationTrack.name + " " + track.name);
                tracekSet[0] = track;
                var clip = track.GetClips() as TimelineClip[];
                anm_length = clip[0].end - clip[0].start;
                //Debug.Log("动作时长:----------" + anm_length);
            }
            else if (track is ControlTrack _ControlTrack) //特效预览
            {
                tracekSet[1] = track;
                //Debug.Log(_ControlTrack.name + " " + track.name);
            }
            else if (track is EffectTrackAsset _EffectTrackAsset)//物体的激活轨道 将它的目标物体 转化成pfefab
            {
                Debug.Log("EffectTrackAsset" + ": " + track.name);
                tracekSet[2] = track;
                var clip = track.GetClips() as TimelineClip[];

                if (clip != null && clip.Length > 0)
                {
                    var temp_playable = clip[0].asset as EffectPlayableAsset;
                    if (temp_playable != null)
                    {
                        _track_effect_config = temp_playable.Config;
                    } 
                }

            }
            foreach (TimelineClip clip in track.GetClips())
            {
                var begin = clip.start;
                var end = clip.end;

            }


        }

        //读取完timeLine 后 写入配置文件
        string unit_id = director.transform.parent.gameObject.name;
        int state_id = int.Parse(director.transform.gameObject.name.Split("@")[0]);
        //int state_id = int.Parse(director.transform.gameObject.name);
        //状态id skillEditor
        Dictionary<int, SkillEditor_EffectItemConfig> skill_dct = new Dictionary<int, SkillEditor_EffectItemConfig>();
        if (tracekSet.TryGetValue(1, out var effect))
        {
            var clips = effect.GetClips() as TimelineClip[];
            foreach (var clip in clips)
            {
                var n = clip.start / anm_length;             
                SkillEditor_EffectItemConfig c = new SkillEditor_EffectItemConfig();
                ControlPlayableAsset x = clip.asset as ControlPlayableAsset;
                //c.obj = (controlPlayableAsset.sourceGameObject.defaultValue as GameObject).transform.parent.gameObject;


                //director 是timeline的组件   Resolve(director.playableGraph.GetResolver()) 是解析引用 反向拿到当前场景中 引用该GameObject资源的对象 这里也就是SkillE
                //节点下
                var o = x.sourceGameObject.Resolve(director.playableGraph.GetResolver());
                c.obj = o.transform.parent == null ? o : o.transform.parent.gameObject;
                c.res_path = $"Effect/{c.obj.name}";
                c.start = n; 
                skill_dct[state_id] = c;


                //Debug.Log($"特效生成点 : {n} ,{c.obj},,子节点:__{o.name}");
                //obj => preafb 做成预制体 Effect/{c.obj.name}
                //确保当前的GameObject 已经不是一个Prefab实例
                bool isCreatePrefab = true;
                if(PrefabUtility.GetPrefabInstanceStatus(c.obj) != PrefabInstanceStatus.NotAPrefab)
                {
                    //Debug.LogError("The GameObject is already a prefab instance");
                    isCreatePrefab =false;
                }

                //创建一个新的Prefab并替换当前GameObject
                string prefabPath = "Assets/Resource/Effect/" + c.obj.name + ".prefab";

                Debug.Log(prefabPath);  
                if (isCreatePrefab && AssetDatabase.LoadAssetAtPath(prefabPath, typeof(GameObject)) ==null)
                {
                    GameObject prefab = PrefabUtility.SaveAsPrefabAssetAndConnect(c.obj,prefabPath,InteractionMode.AutomatedAction);
                }
            }
        }

        //把数据转换成 scriptObject  state_config
        //1 、存特效 播特效的时间点
        //state id =  , name = stateId @ animationName;

        EffectConfig state_EffectConfig = null;
        var anmConfig = Resources.Load<StateScripttableObject>($"Config/StateConfig/{unit_id}");

        if (anmConfig == null)
        {
            Debug.LogError($"缺失{unit_id}配置");
            return;
        }
        Dictionary<int, StateEntity> state_config = new Dictionary<int, StateEntity>();
        for(int i = 0;i< anmConfig.states.Count; i++) 
        {
            if (state_id == anmConfig.states[i].id)
            {
                //对该状态的一些配置写入timeLine的内容
                StateEntity state = anmConfig.states[i];
                if (state.effectConfigs == null)
                {
                    state.effectConfigs = new List<EffectConfig> ();
                }
                var config = skill_dct[state_id];
                //EffectConfig effectConfig = null;
                bool need_add = true;
                if (state.effectConfigs != null)
                {
                    if(state.effectConfigs.Count == 0)
                    {
                        //if (_track_effect_config != null)
                        //{
                        //    //把轨道上的effectConfig 转化成 资源的 stateConfig effectConfig 
                        //    var config_json = JsonUtility.ToJson(_track_effect_config);

                        //}
                    }
                    else
                    {
                        //for(int i)
                        //路径一致的 检查是否有相同路径的 更新一下                      
                        for(int j = 0; j< state.effectConfigs.Count;j++)
                        {
                            Debug.Log(state.effectConfigs[j].res_path);
                            if (state.effectConfigs[j].res_path == $"Effect/{config.obj.name}")
                            {
                                need_add = false;
                                state_EffectConfig = state.effectConfigs[j];
                                break;
                            }
                        }
                    }

                    if (_track_effect_config != null)
                    {
                        _track_effect_config.trigger = (float)Math.Round(config.start, 3);
                        _track_effect_config.res_path = $"Effect/{config.obj.name}";
                        if (need_add) //为什么要这样写代码？？？？
                        {
                           state.effectConfigs.Add(_track_effect_config);
                        }
                        else
                        {
                            var json = JsonUtility.ToJson(_track_effect_config);
                            state_EffectConfig = JsonUtility.FromJson<EffectConfig>(json);  //为啥要这样写
                        }

                        EditorUtility.SetDirty(anmConfig);
                        AssetDatabase.SaveAssets();
                        AssetDatabase.Refresh();
                    }
                    

                }
            } 
        }
    }

}

public class SkillEditor_EffectItemConfig 
{
    public GameObject obj;
    public double start;
    public string res_path;
    public EffectConfig effectConfig;
}


